package world;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.math.BigDecimal;

import org.junit.BeforeClass;
import org.junit.Test;

import exceptions.IllegalPositionException;

import world.conditions.ConditionAtLeast200Celcius;
import world.placement.Direction;
import world.placement.Position;
import world.square.Rock;
import world.square.Square;
import world.square.Temperature;
import world.square.TemperatureScale;

public class CompositeTest {

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		//OPZETTEN VAN DRIELAGENSTRUCTUUR
		composite1 = new Composite<Square>(10, 10, 10);
		
		level = new Level<Square>(2, 2);
		levelPosition = new Position (1, 0, 0);
		levelPosition2 = new Position(0, 1, 0);		
		
		composite2 = new Composite<Square>(7, 7, 7);
		
		shaft = new Shaft<Square>(Direction.EAST, 3);
		shaftPosition = new Position(3, 0, 0);
		shaftPosition2 = new Position(2, 0, 0);
		
		level2 = new Level<Square>(2, 3);
		level2Position = new Position (1, 0, 0);
		level2Position2 = new Position(2, 0, 0);	
		
		composite3 = new Composite<Square>(2, 2, 2);
		shaft2 = new Shaft<Square>(Direction.NORTH, 2);
		shaft2Position = new Position(0, 1, 0);
		
		position000 = new Position(0, 0, 0);
		position111 = new Position(1, 1, 1);
		position012 = new Position(0, 1, 2);
		position101 = new Position(1, 0, 1);
		position565 = new Position(5, 6, 5);

		composite1.addSubDungeon(level, position000);
		composite1.addSubDungeon(composite2, position012);
		composite2.addSubDungeon(shaft, position101);
		//composite2.addSubDungeon(level2, position000);
		composite2.addSubDungeon(composite3, position012);
		
		composite3.addSubDungeon(shaft2, position101);
		
		
		shaft.addSquare(square1, shaftPosition);
		shaft.addSquare(square2, shaftPosition2);
		shaft2.addSquare(square1, shaft2Position);
		level.addSquare(square3, levelPosition);
		level.addSquare (square4, levelPosition2);
		level2.addSquare(square5, level2Position);
		level2.addSquare (square6, level2Position2);				
	}
	private static Level<Square> level;
	private static Level<Square> level2;
	private static Shaft<Square> shaft;
	private static Shaft<Square> shaft2;
	private static Composite<Square> composite1;
	private static Composite<Square> composite2;
	private static Composite<Square> composite3;
	
	private static Position shaftPosition;
	private static Position shaftPosition2;
	private static Position shaft2Position;

//	private static Position shaft2Position2;
	private static Position levelPosition;
	private static Position levelPosition2;
	private static Position level2Position;
	private static Position level2Position2;
	private static Position position000;
	private static Position position111;
	private static Position position012;
	private static Position position101;
	private static Position position565;


	private static Square square1 = new Square(new Temperature(new BigDecimal ("3200"), TemperatureScale.CELCIUS), new BigDecimal ("20"));
	private static Square square2= new Square(new Temperature(new BigDecimal ("3200"), TemperatureScale.CELCIUS), new BigDecimal ("20"));
	
	private static Square square3 = new Square(new Temperature(new BigDecimal ("3200"), TemperatureScale.CELCIUS), new BigDecimal ("20"));
	private static Square square4= new Square();
	
	private static Square square5 = new Rock();
	private static Square square6= new Square(new Temperature(new BigDecimal ("3200"), TemperatureScale.CELCIUS), new BigDecimal ("20"));
	
	@Test
	public final void isValidSubDungeon_FalseCase(){
		assertTrue (composite2.isValidSubDungeon(level2));
	}
	
	@Test
	public final void containingDungeon_SingleCase(){
		assertEquals(shaft.getContainingDungeon(), composite2);
		assertEquals(composite2.getContainingDungeon(), composite1);
		assertEquals(level.getContainingDungeon(), composite1);
	}
	
	@Test
	public final void getRootDungeon_SingleCase(){
		assertEquals (shaft.getRootDungeon(), composite1);
		assertEquals (level.getRootDungeon(), composite1);
	}
	
	@Test
	public final void containsSubDungeon_TrueCase(){
		assertTrue (composite1.containsSubDungeon(composite2));
	}
	
	
	@Test
	public final void subDungeonFitsIn_TrueCase(){
		assertTrue (composite1.subDungeonFitsIn(level, position000));

	}
	
	@Test
	public final void subDungeonFitsIn_FalseCase(){
		assertFalse (composite2.subDungeonFitsIn(level, position565));
	}
	
	@Test
	public final void overlap_TrueCase(){
		assertTrue (composite1.hasOverlap(level, position000));
	}
	
	@Test
	public final void overlap_FalseCase() throws IllegalPositionException{
		assertFalse(composite2.hasOverlap(level2, position000));
		assertFalse (composite2.hasOverlap(level2, position111));
		composite2.addSubDungeon(level2, position000);
	}
	@Test(expected = IllegalArgumentException.class)
	public final void addSubDungeon_ExceptionalCase() throws IllegalPositionException{
		composite2.addSubDungeon(level2, null);
	}
	
	@Test
	public final void getRocksWithTemperatureAtLeast200_SingleCase(){
		assertEquals (1, composite1.getSquaresWithCondition(new ConditionAtLeast200Celcius()).size());	
	}
}
